import { isReferee } from "@/func";
import { Player } from "@minecraft/server";
import { Dimensions } from "@sapi-game/constants";
import { EntityInteractionListener } from "@/base/components/playerInteractListener";
import { Game, GameComponent } from "@sapi-game/main";
import { Duration } from "@sapi-game/utils";
import { DimensionIds, EntityTypeIds } from "@sapi-game/utils/vanila-data";
import { HubGameList } from "../games";
import { HubState } from "../hubState";

interface HubEntityData {
    entityId: string;
    animationName: string;
    interval: Duration;
}

export interface HubGameData {
    entityData?: HubEntityData;
    buttonLoc?: [number, number, number];
    onInteract: (player: Player) => void;
    requirePerm?: boolean;
}

export class HubGameComponent extends GameComponent<HubState> {
    games: HubGameData[] = HubGameList;

    override onAttach(): void {
        this.games.forEach((game) => this.register(game));
    }

    private register(game: HubGameData) {
        if (game.entityData) {
            this.registerEntityTask(
                game.entityData,
                game.onInteract,
                game.requirePerm
            );
        }
        if (game.buttonLoc) {
            this.bindButton(game);
        }
    }

    /** 添加一个动画任务 */
    addTask(game: HubGameData): void {
        this.games.push(game);
        this.register(game);
    }

    /**注册hub按钮 */
    bindButton(game: HubGameData) {
        this.subscribe(
            Game.events.buttonPush,
            (e) => {
                const p = e.source as Player;
                if (game.requirePerm && !isReferee(p)) {
                    p.sendMessage("你不是裁判，无法操作");
                } else {
                    game.onInteract(p);
                }
            },
            {
                dimensionId: DimensionIds.Overworld,
                loc: game.buttonLoc!,
                sourceType: EntityTypeIds.Player,
            }
        );
    }

    /** 注册hub实体 */
    private registerEntityTask(
        game: HubEntityData,
        onInteract: (player: Player) => void,
        requirePerm?: boolean
    ): void {
        const listener = this.state.getComponent(EntityInteractionListener);

        this.subscribe(
            Game.events.interval,
            () => {
                Dimensions.Overworld.getEntities({
                    type: game.entityId,
                }).forEach((entity) =>
                    entity.playAnimation(game.animationName, {
                        players: this.state.region.getEntitesInRegion({
                            type: EntityTypeIds.Player,
                        }) as Player[],
                    })
                );
            },
            game.interval
        );

        listener.bind(game.entityId, (p) => {
            if (requirePerm && !isReferee(p)) {
                p.sendMessage("你不是裁判，无法操作");
            } else {
                onInteract(p);
            }
        });
    }
}
